package com.example.bootcaffeinecache.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
public class CacheConfig {


    /**
     * 创建基于Caffeine的Cache Manager
     * 初始化一些key存入
     *
     * @return
     */
    @Bean
    // 如果所用Spring的缓存注解，且并存多个缓存（Redis，Caffeine）,使用该注解确定用谁
    // 在@Cacheable注解中没指定 cacheManager 则使用标记为primary的那个
    @Primary
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        ArrayList<CaffeineCache> caches = Lists.newArrayList();
        initCacheBean().forEach(cacheBean -> {
            // 添加两种缓存策略
            caches.add(new CaffeineCache(cacheBean.getKey(),
                    Caffeine.newBuilder()
                            .initialCapacity(50)
                            .maximumSize(cacheBean.getMaximumSize())
                            .expireAfterWrite(cacheBean.getTtl(), TimeUnit.SECONDS)
                            .refreshAfterWrite(60, TimeUnit.SECONDS)// Bean过去策略和时间
                            .recordStats()
                            .build()));
        });
        cacheManager.setCaches(caches);
        return cacheManager;
    }

    /**
     * 初始化一些cache策略
     *
     * @return {@link List}<{@link CacheBean}>
     */
    private List<CacheBean> initCacheBean() {
        List<CacheBean> list = Lists.newArrayList();
        CacheBean userCache = new CacheBean();
        userCache.setKey("fooguiCache");
        userCache.setTtl(60);
        userCache.setMaximumSize(10000);

        CacheBean deptCache = new CacheBean();
        deptCache.setKey("userCache");
        deptCache.setTtl(60);
        deptCache.setMaximumSize(10000);

        list.add(userCache);
        list.add(deptCache);

        return list;
    }

    @Getter
    @Setter
    static class CacheBean {
        private String key;
        private long ttl;
        private long maximumSize;
    }
}
